export default class WebSocketClient {
  constructor(url) {
    this.url = url;
    this.ws = null;
    this.heartbeatInterval = 30000; // 30秒发送一次心跳
    this.reconnectInterval = 2000;  // 初始重连间隔
    this.maxReconnectInterval = 30000; // 最大重连间隔
    this.reconnectTimer = null;
    this.heartbeatTimer = null;
    this.reconnectAttempts = 0;     // 重连尝试次数
    this.maxReconnectAttempts = 10; // 最大重连次数
    this.connect();
  }

  // 连接 WebSocket
  connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log('WebSocket 连接成功');
      this.reconnectAttempts = 0;
      // this.startHeartbeat();
      this.onOpenCallback?.();
    };

    this.ws.onmessage = (event) => {
      console.log('收到消息:', event.data);
      // 处理服务器响应
      if (event.data === 'ping') {
        this.onPong();
      } else {
        if (event.data === 'ping') return
        this.onMessageCallback?.(event.data);
      }
    };

    this.ws.onclose = (event) => {
      console.log(`WebSocket 连接关闭，代码: ${event.code}`);
      this.stopHeartbeat();
      this.scheduleReconnect();
      this.onCloseCallback?.(event);
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket 发生错误:', error);
      this.stopHeartbeat();
      this.ws.close(); // 触发 onclose 进行重连
      this.onErrorCallback?.(error);
    };
  }

  // 发送心跳
  sendHeartbeat() {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      console.log('发送心跳: ping');
      this.ws.send('ping');
      // 设置超时检测
      this.heartbeatTimeout = setTimeout(() => {
        console.log('心跳超时，关闭连接');
        this.ws.close();
      }, this.heartbeatInterval);
    }
  }

  // 处理 pong 响应
  onPong() {
    console.log('收到心跳响应: ping');
    clearTimeout(this.heartbeatTimeout);
  }

  // 启动心跳
  startHeartbeat() {
    this.stopHeartbeat();
    this.heartbeatTimer = setInterval(() => {
      this.sendHeartbeat();
    }, this.heartbeatInterval);
  }

  // 停止心跳
  stopHeartbeat() {
    clearInterval(this.heartbeatTimer);
    clearTimeout(this.heartbeatTimeout);
  }

  // 安排重连
  scheduleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('达到最大重连次数，停止尝试');
      this.onMaxReconnectsCallback?.();
      return;
    }

    // 指数退避：每次重连间隔翻倍，但不超过最大值
    const delay = Math.min(
      this.reconnectInterval * Math.pow(2, this.reconnectAttempts),
      this.maxReconnectInterval
    );

    console.log(`尝试重连 #${this.reconnectAttempts + 1}，${delay}ms 后...`);
    this.reconnectAttempts++;

    this.reconnectTimer = setTimeout(() => {
      this.connect();
    }, delay);
  }

  // 发送消息
  send(message) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(message);
    } else {
      console.error('WebSocket 未连接，无法发送消息');
      // 可选择缓存消息，重连后发送
      this.onSendErrorCallback?.(message);
    }
  }

  // 关闭连接
  close() {
    console.log('手动关闭 WebSocket 连接');
    clearInterval(this.reconnectTimer);
    this.stopHeartbeat();
    this.ws.close();
  }

  // 设置回调函数
  onOpen(callback) {
    this.onOpenCallback = callback;
    return this;
  }

  onMessage(callback) {
    this.onMessageCallback = callback;
    return this;
  }

  onClose(callback) {
    this.onCloseCallback = callback;
    return this;
  }

  onError(callback) {
    this.onErrorCallback = callback;
    return this;
  }

  onMaxReconnects(callback) {
    this.onMaxReconnectsCallback = callback;
    return this;
  }

  onSendError(callback) {
    this.onSendErrorCallback = callback;
    return this;
  }
}
